---------------Station 5---------------
A 4am crack                  2018-04-05
---------------------------------------

Name: Station 5
Genre: strategy
Year: 1984
Publisher: Micro-Fun
Platform: Apple ][+ or later
Media: 5.25-inch disk
Sides: 1
OS: DOS 3.3
Previous cracks: Apple Bandit / MPG

This disk was automatically cracked by
Passport. Here is the transcript:

                 --v--

READING FROM S6,D1
T00,S00 FOUND DOS 3.3 BOOTLOADER
USING DISK'S OWN RWTS
WRITING TO S5,D2
T02,S02 VOLUME NAME IS DISK VOLUME 254
T00,S03,$91: 9E -> DE
T00,S03,$9B: E7 -> AA
T00,S03,$35: D5 -> DE
T00,S02,$9E: D5 -> DE
CRACK COMPLETE. PRESS ANY KEY

                 --^--

[Narrator]
But the crack was not complete.

The copy that Passport produces is in a
standard format, fully readable by
third-party tools. But when I boot it,
the disk starts loading DOS and starts
grinding.

The RWTS code for matching prologues
and epilogues looks correct, but
Passport has missed something somewhere
else. The RWTS is almost identical to a
standard DOS 3.3 disk, which makes
comparison easier.

And lo, on T00,S08, I find a suspicious
JMP at $BE38:

                 --v--

T00,S08 ($BE00)
----------- DISASSEMBLY MODE ----------
0038:4C 6A BA       JMP   $BA6A   <-- !
003B:28             PLP
003C:A2 00          LDX   #$00
003E:86 26          STX   $26
0040:20 C2 B8       JSR   $B8C2
0043:AE F8 05       LDX   $05F8
0046:18             CLC
0047:24 38          BIT   $38
0049:A0 0D          LDY   #$0D
004B:91 48          STA   ($48),Y
004D:BD 88 C0       LDA   $C088,X
0050:60             RTS

                 --^--

$BA6A is in a region that is generally
unused. (Later versions of DOS 3.3 used
it to patch buggy DOS routines, but not
the RWTS itself. Pronto-DOS uses it too
but at an entry point of $BA69. Anyway,
this is suspicious.)

$BAxx is usually on T00,S04, and this
disk is no different.

                 --v--

T00,S04 ($BA00)
----------- DISASSEMBLY MODE ----------
; code to handle the real error cases
; (which would be handled by the code
; at $BE38 if we hadn't jumped here)
006A:08             PHP
006B:90 03          BCC   $0070
006D:4C C9 BD       JMP   $BDC9

; check track and sector (in zero page,
; put there by the address field parser
; at $B944)
0070:A5 2D          LDA   $2D
0072:C9 00          CMP   #$00
0074:D0 0D          BNE   $0083
0076:A5 2E          LDA   $2E
0078:C9 16          CMP   #$16
007A:F0 07          BEQ   $0083
007C:28             PLP

; oh what fresh hell is this
007D:20 AF BE       JSR   $BEAF
0080:08             PHP
0081:B0 EA          BCS   $006D
0083:28             PLP
0084:4C 3C BE       JMP   $BE3C

                 --^--

And we're back to sector 8.

                 --v--

T00,S08 ($BE00)
----------- DISASSEMBLY MODE ----------
00AF:A0 00          LDY   #$00
00B1:84 26          STY   $26
00B3:84 27          STY   $27

; skip over self-sync nibbles ($FF)
; while counting them
00B5:BD 8C C0       LDA   $C08C,X
00B8:10 FB          BPL   $00B5
00BA:C9 FF          CMP   #$FF
00BC:D0 08          BNE   $00C6
00BE:E6 26          INC   $26
00C0:D0 F3          BNE   $00B5
00C2:E6 27          INC   $27
00C4:D0 EF          BNE   $00B5

; branch if we find the first nibble of
; the original disk's custom epilogue
; (it was $9E on this disk but I think
; this routine is generic enough to
; handle some variations)
00C6:C9 9E          CMP   #$9E
00C8:F0 3D          BEQ   $0107
00CA:C9 CF          CMP   #$CF
00CC:F0 35          BEQ   $0103

; otherwise check a lookup table using
; the nibble value as the index
00CE:A8             TAY
00CF:B9 9F BE       LDA   $BE9F,Y

; must be < $80, otherwise fail
00D2:30 37          BMI   $010B

; otherwise use that lookup value as an
; index into another table and match
; the next disk nibble against that
00D4:A8             TAY
00D5:BD 8C C0       LDA   $C08C,X
00D8:10 FB          BPL   $00D5
00DA:D9 9F BF       CMP   $BF9F,Y

; must match, otherwise fail
00DD:D0 2C          BNE   $010B
00DF:E6 26          INC   $26
00E1:D0 02          BNE   $00E5
00E3:E6 27          INC   $27

; compare next disk nibble to another
; lookup table
00E5:BD 8C C0       LDA   $C08C,X
00E8:10 FB          BPL   $00E5
00EA:D9 A7 BF       CMP   $BFA7,Y
00ED:D0 1C          BNE   $010B
00EF:EA             NOP
00F0:EA             NOP
00F1:EA             NOP

; and again
00F2:BD 8C C0       LDA   $C08C,X
00F5:10 FB          BPL   $00F2
00F7:D9 AF BF       CMP   $BFAF,Y
00FA:D0 0F          BNE   $010B
00FC:B9 B7 BF       LDA   $BFB7,Y
00FF:D0 2A          BNE   $012B

[continued on T00,S09]

0101:F0 19          BEQ   $001C
0103:A0 05          LDY   #$05
0105:D0 CE          BNE   $FFD5
0107:A0 06          LDY   #$06
0109:D0 CA          BNE   $FFD5

; failure path is here -- set carry and
; return to caller (which propagates it
; to the code that called the RWTS to
; read a sector, which explains all the
; grinding)
010B:38             SEC
010C:60             RTS

...

; finally, check the nibble counter (in
; zero page $26/$27)
0161:A9 11          LDA   #$11
0163:18             CLC
0164:65 26          ADC   $26
0166:85 26          STA   $26
0168:90 02          BCC   $006C
016A:E6 27          INC   $27

; get track
016C:A0 04          LDY   #$04
016E:B1 48          LDA   ($48),Y
0170:A8             TAY

; use track number as an index to look
; up the correct nibble count (which
; varies by track)
0171:B9 56 BC       LDA   $BC56,Y
0174:38             SEC
0175:E5 26          SBC   $26
0177:30 92          BMI   $000B
0179:C9 05          CMP   #$05
017B:B0 8E          BCS   $000B
017D:B9 7A BC       LDA   $BC7A,Y
0180:C5 27          CMP   $27
0182:D0 87          BNE   $000B

; success path clears carry and returns
; to caller (again, this will end up
; being the RWTS "no error" flag that
; is returned to the original sector
; read code)
0184:18             CLC
0185:60             RTS

                 --^--

So... a nibble count, integrated into
the RWTS itself, conditionally called
from $BA6A which is called from $BE38.
No side effects. We can bypass the
entire thing by changing the "JMP" at
$BE38 back to standard DOS 3.3 code,
which is "PHP / BCS $BDC9".

T00,S08,$38: 4C6ABA -> 08B08E

]PR#6
...works, and it is glorious...

Grepping through 5000 other disk images
(which is a perfectly reasonable number
of disk images to have lying around on
one's hard drive in 2018), I see that
Micro-Fun used an identical protection
on several other disks. And you know
what that means... I get to update
Passport to support this protection.

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1728
------------------EOF------------------
